package com.ruoyi.module.privateaccount.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.module.accountrecords.domain.BizAccountRecords;
import com.ruoyi.module.accountrecords.mapper.BizAccountRecordsMapper;
import com.ruoyi.module.constants.BizConstants;
import com.ruoyi.module.purchaserecord.domain.BizPurchaseRecord;
import com.ruoyi.module.purchaserecord.mapper.BizPurchaseRecordMapper;
import com.ruoyi.module.utils.BigDecimalChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.ruoyi.module.privateaccount.mapper.BizPrivateAccountMapper;
import com.ruoyi.module.privateaccount.domain.BizPrivateAccount;
import com.ruoyi.module.privateaccount.service.IBizPrivateAccountService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 个人账户Service业务层处理
 * 
 * @author zhaoxi
 * @date 2023-09-08
 */
@Service
public class BizPrivateAccountServiceImpl implements IBizPrivateAccountService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(BizPrivateAccountServiceImpl.class);
    @Resource
    private BizPrivateAccountMapper bizPrivateAccountMapper;

    @Resource
    private BizPurchaseRecordMapper bizPurchaseRecordMapper;

    @Resource
    private BizAccountRecordsMapper bizAccountRecordsMapper;

//    @Resource
//    private BigDecimalChain bigDecimalChain;

    /**
     * 查询个人账户
     * 
     * @param id 个人账户主键
     * @return 个人账户
     */
    @Override
    public BizPrivateAccount selectBizPrivateAccountById(Long id)
    {
        return bizPrivateAccountMapper.selectBizPrivateAccountById(id);
    }

    /**
     * 查询个人账户列表
     * 
     * @param bizPrivateAccount 个人账户
     * @return 个人账户
     */
    @Override
    public List<BizPrivateAccount> selectBizPrivateAccountList(BizPrivateAccount bizPrivateAccount)
    {
        return bizPrivateAccountMapper.selectBizPrivateAccountList(bizPrivateAccount);
    }

    /**
     * 新增个人账户
     * 
     * @param bizPrivateAccount 个人账户
     * @return 结果
     */
    @Override
    public int insertBizPrivateAccount(BizPrivateAccount bizPrivateAccount)
    {
        bizPrivateAccount.setCreateTime(DateUtils.getNowDate());
        return bizPrivateAccountMapper.insertBizPrivateAccount(bizPrivateAccount);
    }

    /**
     * 修改个人账户
     * 
     * @param bizPrivateAccount 个人账户
     * @return 结果
     */
    @Override
    public int updateBizPrivateAccount(BizPrivateAccount bizPrivateAccount)
    {
        bizPrivateAccount.setUpdateTime(DateUtils.getNowDate());
        return bizPrivateAccountMapper.updateBizPrivateAccount(bizPrivateAccount);
    }

    /**
     * 批量删除个人账户
     * 
     * @param ids 需要删除的个人账户主键
     * @return 结果
     */
    @Override
    public int deleteBizPrivateAccountByIds(Long[] ids)
    {
        return bizPrivateAccountMapper.deleteBizPrivateAccountByIds(ids);
    }

    /**
     * 删除个人账户信息
     * 
     * @param id 个人账户主键
     * @return 结果
     */
    @Override
    public int deleteBizPrivateAccountById(Long id)
    {
        return bizPrivateAccountMapper.deleteBizPrivateAccountById(id);
    }


    /**
     * 产品返利，按T+1天计算（定时任务)
     *
     * @param bizPrivateAccount 个人账户
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult productRebate(BizPrivateAccount bizPrivateAccount) {

        try {

            BizPurchaseRecord bizPurchaseRecord = new BizPurchaseRecord();
            //获取30天内所有产品购买记录
            List<BizPurchaseRecord> purchaseRecordList = bizPurchaseRecordMapper.selectBizPurchaseRecordListInThirtyDays(bizPurchaseRecord);
            //获取今天到期的所有产品购买记录
            List<BizPurchaseRecord> purchaseRecordList1 = bizPurchaseRecordMapper.selectBizPurchaseRecordListEqualsThirtyDays(bizPurchaseRecord);

            //每日返利
            if(!CollectionUtils.isEmpty(purchaseRecordList)) {
                //根据产品购买记录的userId集合，查出的个人账户集合
                List<BizPrivateAccount> privateAccountList = getPrivateAccountList(purchaseRecordList);
                if (!CollectionUtils.isEmpty(privateAccountList)) {
                    //每个人的账户返利，更新账户集合
                    List<BizPrivateAccount> privateAccountList1 = updateAccountList(purchaseRecordList, privateAccountList);
                    bizPrivateAccountMapper.updateBatch(privateAccountList1);
                }
            }

            //到30天的产品返利
            if(!CollectionUtils.isEmpty(purchaseRecordList1)){
                //根据产品购买记录的userId集合，查出的个人账户集合
                List<BizPrivateAccount> privateAccountList = getPrivateAccountList(purchaseRecordList1);
                if (!CollectionUtils.isEmpty(privateAccountList)) {
                    //每个人的产品到期利息，更新账户集合
                    List<BizPrivateAccount> privateAccountList1 = updateExpireAccountList(purchaseRecordList1, privateAccountList);
                    bizPrivateAccountMapper.updateBatch(privateAccountList1);
                }
            }

            return AjaxResult.success();
        } catch (Exception e) {
            //发生异常时回滚事务
            throw new RuntimeException("产品返利操作失败", e);
        }
    }

    /**
     * 根据产品购买记录获取对应的个人账户列表
     *
     * @param purchaseRecordList 产品购买记录列表
     * @return 个人账户列表
     */
    private List<BizPrivateAccount> getPrivateAccountList(List<BizPurchaseRecord> purchaseRecordList) {
        // 提取产品购买记录中的userId，并去重
        List<Long> userIdList = purchaseRecordList.stream()
                .filter(Objects::nonNull)
                .map(BizPurchaseRecord::getUserId)
                .distinct()
                .collect(Collectors.toList());
        // 根据userId集合查询个人账户列表
        return bizPrivateAccountMapper.selectByUserIdList(userIdList);
    }

    /**
     * 根据投资金额计算返利
     * 计入个人账户流水记录
     *
     * @param purchaseRecordList
     * @param privateAccountList
     * @return privateAccountList
     */
    private List<BizPrivateAccount> updateAccountList(List<BizPurchaseRecord> purchaseRecordList, List<BizPrivateAccount> privateAccountList) {
        //个人账户流水记录列表
        List<BizAccountRecords> accountRecordsList = new ArrayList<>();
        // 将privateAccountList转换为Map，以便根据用户id快速查找账户
        Map<Long, BizPrivateAccount> privateAccountMap = new HashMap<>();
        for (BizPrivateAccount privateAccount : privateAccountList) {
            privateAccountMap.put(privateAccount.getUserId(), privateAccount);
        }
        // 遍历purchaseRecordList，更新账户金额并生成账户流水记录
        for (BizPurchaseRecord purchaseRecord : purchaseRecordList) {
            //获取用户id
            Long userId = purchaseRecord.getUserId();
            //购买类型
            String purchaseType = purchaseRecord.getPurchaseType();
            //对应的个人账户
            BizPrivateAccount privateAccount = privateAccountMap.get(userId);
            if (privateAccount != null) {
                //账户初始金额
                BigDecimal accountFunds = privateAccount.getaccountFunds();
                //根据账户金额，计算返利后的账户总金额
                BigDecimal accountFunds1 = updateAccountFunds(accountFunds, purchaseType);
                //计算返利金额，并放入个人账户流水记录对象列表
                BizAccountRecords accountRecords = getAccountRecords(accountFunds1, accountFunds, userId);
                if (accountRecords != null) {
                    accountRecordsList.add(accountRecords);
                }
                //更新个人账户金额
                privateAccount.setAccountFunds(accountFunds1);
            }
        }
        if (!CollectionUtils.isEmpty(accountRecordsList)) {
            // 批量插入个人账户流水记录
            insertBatchBizAccountRecords(accountRecordsList);
        }
        return privateAccountList;
    }

    /**
     * 根据投资金额计算30天到期利息
     *计入个人账户流水记录
     *
     *@param purchaseRecordList
     * @return privateAccountList
     */
    private List<BizPrivateAccount> updateExpireAccountList( List<BizPurchaseRecord> purchaseRecordList,List<BizPrivateAccount> privateAccountList){

        //个人账户流水记录列表
        List<BizAccountRecords> accountRecordsList = new ArrayList<>();
        // 将privateAccountList转换为Map，以便根据用户id快速查找账户
        Map<Long, BizPrivateAccount> privateAccountMap = new HashMap<>();
        for (BizPrivateAccount privateAccount : privateAccountList) {
            privateAccountMap.put(privateAccount.getUserId(), privateAccount);
        }
        // 遍历purchaseRecordList，更新账户金额并生成账户流水记录
        for (BizPurchaseRecord purchaseRecord : purchaseRecordList) {
            //获取用户id
            Long userId = purchaseRecord.getUserId();
            //购买类型
            String purchaseType = purchaseRecord.getPurchaseType();
            //对应的个人账户
            BizPrivateAccount privateAccount = privateAccountMap.get(userId);
            if (privateAccount != null) {
                //账户初始金额
                BigDecimal accountFunds = privateAccount.getaccountFunds();
                //根据投资金额，计算到期返利，之后的账户总额
                BigDecimal accountFunds1 = updateExpireAccountFunds(accountFunds, purchaseType);
                //计算返利金额，并放入个人账户流水记录对象列表
                BizAccountRecords accountRecords = getAccountRecords(accountFunds1, accountFunds, userId);
                if (accountRecords != null) {
                    accountRecordsList.add(accountRecords);
                }
                //更新个人账户金额
                privateAccount.setAccountFunds(accountFunds1);
            }
        }
        if (!CollectionUtils.isEmpty(accountRecordsList)) {
            // 批量插入个人账户流水记录
            insertBatchBizAccountRecords(accountRecordsList);
        }
        return privateAccountList;
    }

    /**
     * 计算利息金额并生成账户流水记录
     *
     * @param accountFunds1 新的账户资金
     * @param accountFunds  原始账户资金
     * @param userId        用户id
     * @return 账户流水记录对象
     */
    private BizAccountRecords getAccountRecords(BigDecimal accountFunds1, BigDecimal accountFunds, Long userId) {
        // 计算利息金额
        BigDecimal sum = BigDecimalChain
                .chain(accountFunds1)
                .sub(accountFunds)
                .get();
        // 判断利息金额是否大于0
        if (sum.compareTo(BigDecimal.ZERO) > 0) {
            // 创建账户记录对象
            BizAccountRecords bizAccountRecords = new BizAccountRecords();
            bizAccountRecords.setUserId(userId);//用户id
            bizAccountRecords.setRecordType(BizConstants.RecordTypeConstant.recordType_1); // 收入
            bizAccountRecords.setAmountType(BizConstants.AmountTypeConstant.amountType_1); // 资金
            bizAccountRecords.setAmountSum(sum); // 金额
            bizAccountRecords.setCreateTime(DateUtils.getNowDate()); // 创建时间
            return bizAccountRecords;
        } else {
            return null;
        }
    }
    /**
     * 批量新增个人账户流水记录
     * @param accountRecordsList 新的账户资金
     *
     */
    private void insertBatchBizAccountRecords(List<BizAccountRecords> accountRecordsList) {
            bizAccountRecordsMapper.insertBatchBizAccountRecords(accountRecordsList);
    }

    /**
     * 每日返利计算规则
     *
     * @param accountFunds      账户余额
     * @param purchaseType      投资金额种类
     */
    private BigDecimal updateAccountFunds(BigDecimal accountFunds, String purchaseType) {
        BigDecimal accountFunds1 ;
        if ("1".equals(purchaseType)) {
            //链式计算每天返还的金额
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("1000"))
                    .div(30, 2)
                    .add(accountFunds.toString())
                    .get();//33.33

        } else if ("2".equals(purchaseType)) {
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("3000"))
                    .div(30, 2)
                    .add(accountFunds.toString())
                    .get();//100.00

        } else if ("3".equals(purchaseType)) {
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("166.66"))
                    .add(accountFunds.toString())
                    .get();//166.66

        } else {
            throw new RuntimeException("每日返利操作失败");
        }
        return accountFunds1;
    }


    /**
     * 30天产品到期时的利息计算规则
     *
     * @param accountFunds      账户余额
     * @param purchaseType      投资金额种类
     */
    private BigDecimal updateExpireAccountFunds(BigDecimal accountFunds, String purchaseType) {
        BigDecimal accountFunds1;
        if ("1".equals(purchaseType)) {
            //链式计算最后一天返还的金额
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("1000"))
                    .mul(0.11D)
                    .add("0.1")
                    .add(accountFunds.toString())
                    .get();

        } else if ("2".equals(purchaseType)) {
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("3000"))
                    .mul(0.15D)
                    .add(accountFunds.toString())
                    .get();

        } else if ("3".equals(purchaseType)) {
            accountFunds1 = BigDecimalChain
                    .chain(new BigDecimal("5000"))
                    .mul(0.17D)
                    .add("0.2")
                    .add(accountFunds.toString())
                    .get();

        } else {
            throw new RuntimeException("每日返利操作失败");
        }
        return accountFunds1;
    }


        public static void main(String[] args) {

            BigDecimal build = BigDecimalChain
                    .chain(new BigDecimal("1000"))
                    .div(30,2)
                    .add("2000")
                    .get();
            System.out.println(build);
            BigDecimal build1 = BigDecimalChain
                    .chain(new BigDecimal("1000"))
                    .mul(0.11D)
                    .add("0.1")
                    .get();
            System.out.println(build1);
            BigDecimal build2 = BigDecimalChain
                    .chain(new BigDecimal("1000"))
                    .mul(11)
                    .div(100)
                    .add("0.10")
                    .get();
            System.out.println(build2);
    }
}



//    /**
//     * 根据投资金额计算30天到期返利
//     *计入个人账户流水记录
//     *
//     *@param purchaseRecordList
//     * @return privateAccountList
//     */
//    private List<BizPrivateAccount> updateExpireAccountList( List<BizPurchaseRecord> purchaseRecordList,List<BizPrivateAccount> privateAccountList){
//
//        //个人账户流水记录列表
//        List<BizAccountRecords> accountRecordsList = new ArrayList<>();
//
//        //个人账户返利
//        for (BizPurchaseRecord purchaseRecord : purchaseRecordList) {
//            //购买类型
//            String purchaseType = purchaseRecord.getPurchaseType();
//
//            for (BizPrivateAccount privateAccount : privateAccountList) {
//                if (purchaseRecord.getUserId() == privateAccount.getUserId()) {
//                    //获取用户id
//                    Long userId = privateAccount.getUserId();
//                    //初始金额
//                    BigDecimal accountFunds = privateAccount.getaccountFunds();
//                    //根据投资金额，计算返利
//                    BigDecimal accountFunds1 = updateExpireAccountFunds(accountFunds, purchaseType);
//
//                    //计算返利金额，并放入个人账户流水记录对象
//                    BizAccountRecords accountRecords = getAccountRecords(accountFunds1, accountFunds, userId);
//                    if (accountRecords != null) {
//                        accountRecordsList.add(accountRecords);
//                    }
//                    //更新个人账户列表金额
//                    privateAccount.setAccountFunds(accountFunds1);
//                }
//            }
//        }

//        if(!CollectionUtils.isEmpty(accountRecordsList)){
//            // 批量插入个人账户流水记录
//            insertBatchBizAccountRecords(accountRecordsList);
//        }
//        return privateAccountList;
//    }

//    /**
//     * 计算每日返利并计入个人账户
//     *
//     * @param bizPrivateAccount 个人账户
//     * @param purchaseType      投资金额种类
//     */
//    private void updateAccountFunds1(BizPrivateAccount bizPrivateAccount, String purchaseType) {
//        BigDecimal accountFunds;
//        if ("1".equals(purchaseType)) {
//            //链式计算每天返还的金额
//            accountFunds = BigDecimalChain
//                    .chain(new BigDecimal("1000"))
//                    .div(30, 2)
//                    .add(bizPrivateAccount.getaccountFunds().toString())
//                    .get();//33.33
//            bizPrivateAccount.setAccountFunds(accountFunds);
//
//        } else if ("2".equals(purchaseType)) {
//            accountFunds = BigDecimalChain
//                    .chain(new BigDecimal("3000"))
//                    .div(30, 2)
//                    .add(bizPrivateAccount.getaccountFunds().toString())
//                    .get();//100.00
//            bizPrivateAccount.setAccountFunds(accountFunds);
//
//        } else if ("3".equals(purchaseType)) {
//            accountFunds = BigDecimalChain
//                    .chain(new BigDecimal("166.66"))
//                    .add(bizPrivateAccount.getaccountFunds().toString())
//                    .get();//166.66
//            bizPrivateAccount.setAccountFunds(accountFunds);
//
//        } else {
//            throw new RuntimeException("每日返利操作失败");
//        }
//
//        bizPrivateAccountMapper.updateBizPrivateAccount(bizPrivateAccount);
//    }

////更新查出来的个人账户列表
//privateAccountList.stream()
//        .filter(account->account.getId()==privateAccount.getId())
//        .findFirst()
//        .ifPresent(account->{
//        account.setAccountFunds(accountFunds1);
//        });

//个人账户返利
//for(BizPurchaseRecord purchaseRecord:purchaseRecordList){
//        //获取购买类型和用户id
//        String purchaseType = purchaseRecord.getPurchaseType();
//        Long userId = purchaseRecord.getUserId();
//        //用户个人账户（唯一）
//        BizPrivateAccount bizPrivateAccount1 = bizPrivateAccountMapper.selectPrivateAccountByUserId(userId);
//        //根据投资金额，计算返利并更改个人账户金额
//        updateAccountFunds1(bizPrivateAccount1, purchaseType);
//        }

